#include "netcfgengine.h"

#include <QDir>

#include <KDirWatch>
#include <KProcess>

#include <Plasma/DataContainer>


static const char *profilesDir = "/etc/network.d";
static const char *stateDir = "/var/run/network/profiles";


class NetcfgEnginePrivate
{
    public:

        NetcfgEngine *q;
        
        KDirWatch profilesDirWatch;

        KDirWatch stateDirWatch;

        QStringList profiles;

        NetcfgEnginePrivate(NetcfgEngine *netcfgEngine);

        void updateProfiles();

        void updateState();
};


// public

NetcfgEngine::NetcfgEngine(QObject* parent, const QVariantList& args) :
    Plasma::DataEngine(parent, args),
    d(new NetcfgEnginePrivate(this))
{
    // never poll
    setPollingInterval(0);

    d->profilesDirWatch.addDir(profilesDir);
    connect(&(d->profilesDirWatch), SIGNAL(dirty(const QString &)), this, SLOT(slotProfilesDirDirty()));
    
    d->stateDirWatch.addDir(stateDir);
    connect(&(d->stateDirWatch), SIGNAL(dirty(const QString &)), this, SLOT(slotStateDirDirty()));
}

void NetcfgEngine::init()
{
    d->updateProfiles();    
}

QStringList NetcfgEngine::sources() const
{
    return d->profiles;
}

// protected

bool NetcfgEngine::sourceRequestEvent(const QString &source)
{
    return updateSourceEvent(source);
}

bool NetcfgEngine::updateSourceEvent(const QString &source)
{
    if (!d->profiles.contains(source)) {
        // no such profile
        return false;
    }

    KProcess process;
    process.setOutputChannelMode(KProcess::SeparateChannels);
    QString command("source %1/%2 && echo $CONNECTION");
    process.setShellCommand(command.arg(profilesDir, source));
    int ret = process.execute();
    if (ret == 0) {
        QByteArray connection = process.readAllStandardOutput().trimmed();
        setData(source, I18N_NOOP("connection"), I18N_NOOP(connection));
    }

    return true;
}

// private Q_SLOTS

void NetcfgEngine::slotProfilesDirDirty()
{
    d->updateProfiles();
    Q_EMIT profilesChanged();
}

void NetcfgEngine::slotStateDirDirty()
{
    d->updateState();
    Q_EMIT stateChanged();
}

// private

NetcfgEnginePrivate::NetcfgEnginePrivate(NetcfgEngine *netcfgEngine) :
    q(netcfgEngine),
    profilesDirWatch(0),
    stateDirWatch(0)
{
}

void NetcfgEnginePrivate::updateProfiles()
{
    QDir dir(profilesDir);
    profiles = dir.entryList(QDir::Files);

    QStringListIterator iterator(profiles);
    while (iterator.hasNext()) {
        q->updateSourceEvent(iterator.next());
    }
    updateState();
}

void NetcfgEnginePrivate::updateState()
{
    QDir dir(stateDir);
    QStringList activeProfiles = dir.entryList(QDir::Files);

    QStringListIterator iterator(profiles);
    QString source;
    while (iterator.hasNext()) {
        source = iterator.next();
        if (activeProfiles.contains(source)) {
            q->setData(source, I18N_NOOP("isActive"), true);
        } else {
            q->removeData(source, I18N_NOOP("isActive"));
            //setData(source, I18N_NOOP("isActive"), false);
        }
    } 
}

#include "netcfgengine.moc"
